Post

Replies

Boosts

Views

Created

NSMetadataQueryDidFinishGathering not being called enough
I have an app where each item in an NSTableView contains an NSMetadataQuery, to listen for updates to image files that contain the keyword associated with the item. If I write the keywords to, RAW files, everything works as expected and the number label in the row gets updated correctly. However, if I write the keywords to XMP sidecar files, the NSMetadataQueryDidFinishGathering callback isn't called enough times and the count of files affected isn't updated correctly. What is more, the number returned on the final call to the callback seems to vary depending on the time of day, weather, etc Here is the code that I have used to create the predicate for finding keywords in XMP files…       let xmpFileTypePredicate = NSPredicate(fromMetadataQueryString: "kMDItemKind = \"XMP sidecar*\"cdwt")!       let xmpKeywordPredicate = NSPredicate(fromMetadataQueryString: "kMDItemTextContent = \"<rdf:li>\(keyword)</rdf:li>\"cdw")!       let xmpKeywordsMetadataQueryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [xmpFileTypePredicate, xmpKeywordPredicate]) Can anyone give me any ideas?
0
0
1.1k
Aug ’22
Replace Threadsafe var with Actor
I have a long established app that uses a threadsafe var to protect an array of URLs from concurrency races, etc… class ThreadsafeVar<T> {   private var value = Optional<T>.none      func callAsFunction() -> T?   {     queue.sync(flags: .barrier) { [unowned self] in value }   }      func set(_ value: T?)   {     queue.async(flags: .barrier) { [unowned self] in self.value = value }   } } What I want to do is substitute an Actor, which I understand will be intrinsically threadsafe. So, I wrote one like this… actor UrlManager {   private var value = [URL]()   func callAsFunction() -> [URL]   {     value   }   func set(_ value: [URL])   {     self.value = value   } } The calling code is in one of four classes, all of which implement a protocol, which contains a read-write var… protocol FolderProtocol { …   var fileURLs: [URL] { get set } } In this particular class, the var is implemented as read-only…   private var urls = ThreadsafeVar<[URL]>()   var fileURLs: [URL]   {     get     {       urls()?.sorted(using: .finder, pathComponent: .fullPath) ?? []     }     set { }   } … the private var being updated from a metadata updating notification handler. Calling the set(_:[URL]) method on the actor poses no problem…       Task { await urls.set(foundURLs) } But, no matter what I try - continuation, try, await, etc, I don't seem to be able to read back the array of URLs from the actor's callAsFunction() method. The fileURLs var is called on the main thread in response to NSCollectionView delegate methods. Other implementing classes don't need the concurrency management as they are fixed once and never changed. Can anyone help me with this one?
1
0
1.3k
Jun ’22
QLThumbnailGenerator loading wrong images
I have an NSCollectionView which is showing thumbnails of images and I have just switched to using QLThumbnailGenerator to fetch them. There are over 6,000 possible images that can be viewed and, if I scroll too fast, I start to get the wrong thumbnails returned from the generator. Is this a bug, or is there something I can do to fix this? Here is the code that is written inside the NSCollectionViewItem derived class…   var request: QLThumbnailGenerator.Request?      func loadImage()   {     if imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")     {       return     }          request = QLThumbnailGenerator.Request(fileAt: url!, size: imageSize, scale: 1.0, representationTypes: [.lowQualityThumbnail])        QLThumbnailGenerator.shared.generateBestRepresentation(for: request!)     {       (thumbnail: QLThumbnailRepresentation?, error: Error?) -> Void in              if let request = self.request       {         QLThumbnailGenerator.shared.cancel(request)       }              DispatchQueue.main.async       {         [unowned self] in                  if self.imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")         {           return         }                  let transition = CATransition()                  transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)                  transition.duration = 0.3                  imageView?.layer?.add(transition, forKey: nil)                  imageView?.image = thumbnail?.nsImage         …
2
0
1.3k
Jun ’21
Problems monitoring a file for metadata changes
I need to monitor a file for when its metadata changes. I'm using the following code I found. final class FileMonitor {   let url: URL   var fileHandle: FileHandle?   var source: DispatchSourceFileSystemObject?   var didReceiveChanges: (() - Void)?   func process(event: DispatchSource.FileSystemEvent)   {     print(String(describing: event))     didReceiveChanges?()   }   func eventHandler()   {     let event = self.source!.data     process(event: event)     createDispatchSource()   }   func createDispatchSource()   {     self.fileHandle = try? FileHandle(forReadingFrom: url)     source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileHandle!.fileDescriptor, eventMask: [.attrib], queue: DispatchQueue.main)     source!.setEventHandler(handler: eventHandler)     source!.setCancelHandler     {       self.fileHandle!.closeFile()     }     source!.resume()   }   init(url: URL) throws   {     self.url = url     createDispatchSource()   }   deinit   {     source!.cancel()   } } The problem is that I am getting nearly 7,000 notifications every time a change is detected, which is causing the CPU to get rather warm. This subject seems to be very poorly documented and after days searching, I don't seem to be able to make things any better. Any ideas please? Joanna
3
0
1.5k
May ’21
How to save and restore position of secondary NSViewController
I have a macOS storyboard with a main Window/View Controller and a couple of "accessory" view controllers that are shown via segues from buttons. The problem is, even having set the restoration ID of both controllers in the storyboard, that they always start at the same position, even if they have been moved. Can anyone help me to get them to reopen in the same place they were when they were closed?
3
0
2.5k
May ’21
Incorrect localization for NSLocationWhenInUseUsageDescription
Greetings allI have an app whose development language is French, which is also its base localization. I also localise it to English.The app makes use of both location services and the calendar.I have created an InfoPlist.strings file and localized both NSCalendarsUsageDescription and NSLocationWhenInUseUsageDescription.My problem is that, although the Base localization (French) of NSCalendarsUsageDescription is correctly used when requesting permission, I can only ever see the French text for NSLocationWhenInUseUsageDescription if I remove the key from the English version of InfoPlist.strings.Many thanks for any help you can give me.
1
0
1.4k
Oct ’16
NSTokenField changing case of second dropped string
I have Swift code that accepts dragging a lowercase string from the TextEdit app. On the first drop, the text is accepted as is but, on the second drop, the first words are capitalised. Any ideas?
Topic: UI Frameworks SubTopic: AppKit
Replies
0
Boosts
0
Views
355
Activity
Oct ’24
How to add menu items to dock item when app not running
Well, it's all in the title. I want to make a URL history list available on the dock item of my macOS app. I found NSDockTilePlugin but nothing on how to implement it. Can anyone help?
Replies
3
Boosts
0
Views
736
Activity
Aug ’24
Find all Finder tags
Can anyone tell me how to retrieve all Finder tags, including user ones that may have been synced from iCloud?
Replies
2
Boosts
0
Views
1.5k
Activity
Feb ’23
NSMetadataQueryDidFinishGathering not being called enough
I have an app where each item in an NSTableView contains an NSMetadataQuery, to listen for updates to image files that contain the keyword associated with the item. If I write the keywords to, RAW files, everything works as expected and the number label in the row gets updated correctly. However, if I write the keywords to XMP sidecar files, the NSMetadataQueryDidFinishGathering callback isn't called enough times and the count of files affected isn't updated correctly. What is more, the number returned on the final call to the callback seems to vary depending on the time of day, weather, etc Here is the code that I have used to create the predicate for finding keywords in XMP files…       let xmpFileTypePredicate = NSPredicate(fromMetadataQueryString: "kMDItemKind = \"XMP sidecar*\"cdwt")!       let xmpKeywordPredicate = NSPredicate(fromMetadataQueryString: "kMDItemTextContent = \"<rdf:li>\(keyword)</rdf:li>\"cdw")!       let xmpKeywordsMetadataQueryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [xmpFileTypePredicate, xmpKeywordPredicate]) Can anyone give me any ideas?
Replies
0
Boosts
0
Views
1.1k
Activity
Aug ’22
Replace Threadsafe var with Actor
I have a long established app that uses a threadsafe var to protect an array of URLs from concurrency races, etc… class ThreadsafeVar<T> {   private var value = Optional<T>.none      func callAsFunction() -> T?   {     queue.sync(flags: .barrier) { [unowned self] in value }   }      func set(_ value: T?)   {     queue.async(flags: .barrier) { [unowned self] in self.value = value }   } } What I want to do is substitute an Actor, which I understand will be intrinsically threadsafe. So, I wrote one like this… actor UrlManager {   private var value = [URL]()   func callAsFunction() -> [URL]   {     value   }   func set(_ value: [URL])   {     self.value = value   } } The calling code is in one of four classes, all of which implement a protocol, which contains a read-write var… protocol FolderProtocol { …   var fileURLs: [URL] { get set } } In this particular class, the var is implemented as read-only…   private var urls = ThreadsafeVar<[URL]>()   var fileURLs: [URL]   {     get     {       urls()?.sorted(using: .finder, pathComponent: .fullPath) ?? []     }     set { }   } … the private var being updated from a metadata updating notification handler. Calling the set(_:[URL]) method on the actor poses no problem…       Task { await urls.set(foundURLs) } But, no matter what I try - continuation, try, await, etc, I don't seem to be able to read back the array of URLs from the actor's callAsFunction() method. The fileURLs var is called on the main thread in response to NSCollectionView delegate methods. Other implementing classes don't need the concurrency management as they are fixed once and never changed. Can anyone help me with this one?
Replies
1
Boosts
0
Views
1.3k
Activity
Jun ’22
Get list of all Finder Tags
Is there any way to retrieve the list of Finder Tags now that the SyncedPreferences option is no longer available for Monterey?
Replies
1
Boosts
0
Views
764
Activity
Apr ’22
Change background of NSHelpManager
Is it possible to change the background colour of an RTF file shown in NSHelpManager to match dark mode?
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
0
Boosts
0
Views
738
Activity
Jun ’21
QLThumbnailGenerator loading wrong images
I have an NSCollectionView which is showing thumbnails of images and I have just switched to using QLThumbnailGenerator to fetch them. There are over 6,000 possible images that can be viewed and, if I scroll too fast, I start to get the wrong thumbnails returned from the generator. Is this a bug, or is there something I can do to fix this? Here is the code that is written inside the NSCollectionViewItem derived class…   var request: QLThumbnailGenerator.Request?      func loadImage()   {     if imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")     {       return     }          request = QLThumbnailGenerator.Request(fileAt: url!, size: imageSize, scale: 1.0, representationTypes: [.lowQualityThumbnail])        QLThumbnailGenerator.shared.generateBestRepresentation(for: request!)     {       (thumbnail: QLThumbnailRepresentation?, error: Error?) -> Void in              if let request = self.request       {         QLThumbnailGenerator.shared.cancel(request)       }              DispatchQueue.main.async       {         [unowned self] in                  if self.imageView?.image != NSImage(imageLiteralResourceName: "Placeholder")         {           return         }                  let transition = CATransition()                  transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)                  transition.duration = 0.3                  imageView?.layer?.add(transition, forKey: nil)                  imageView?.image = thumbnail?.nsImage         …
Replies
2
Boosts
0
Views
1.3k
Activity
Jun ’21
Problems monitoring a file for metadata changes
I need to monitor a file for when its metadata changes. I'm using the following code I found. final class FileMonitor {   let url: URL   var fileHandle: FileHandle?   var source: DispatchSourceFileSystemObject?   var didReceiveChanges: (() - Void)?   func process(event: DispatchSource.FileSystemEvent)   {     print(String(describing: event))     didReceiveChanges?()   }   func eventHandler()   {     let event = self.source!.data     process(event: event)     createDispatchSource()   }   func createDispatchSource()   {     self.fileHandle = try? FileHandle(forReadingFrom: url)     source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileHandle!.fileDescriptor, eventMask: [.attrib], queue: DispatchQueue.main)     source!.setEventHandler(handler: eventHandler)     source!.setCancelHandler     {       self.fileHandle!.closeFile()     }     source!.resume()   }   init(url: URL) throws   {     self.url = url     createDispatchSource()   }   deinit   {     source!.cancel()   } } The problem is that I am getting nearly 7,000 notifications every time a change is detected, which is causing the CPU to get rather warm. This subject seems to be very poorly documented and after days searching, I don't seem to be able to make things any better. Any ideas please? Joanna
Replies
3
Boosts
0
Views
1.5k
Activity
May ’21
How to save and restore position of secondary NSViewController
I have a macOS storyboard with a main Window/View Controller and a couple of "accessory" view controllers that are shown via segues from buttons. The problem is, even having set the restoration ID of both controllers in the storyboard, that they always start at the same position, even if they have been moved. Can anyone help me to get them to reopen in the same place they were when they were closed?
Replies
3
Boosts
0
Views
2.5k
Activity
May ’21
Incorrect localization for NSLocationWhenInUseUsageDescription
Greetings allI have an app whose development language is French, which is also its base localization. I also localise it to English.The app makes use of both location services and the calendar.I have created an InfoPlist.strings file and localized both NSCalendarsUsageDescription and NSLocationWhenInUseUsageDescription.My problem is that, although the Base localization (French) of NSCalendarsUsageDescription is correctly used when requesting permission, I can only ever see the French text for NSLocationWhenInUseUsageDescription if I remove the key from the English version of InfoPlist.strings.Many thanks for any help you can give me.
Replies
1
Boosts
0
Views
1.4k
Activity
Oct ’16